package cn.itsource.ymcc.service.impl;

import cn.itsource.ymcc.constant.CourseConstants;
import cn.itsource.ymcc.constant.RConst;
import cn.itsource.ymcc.domain.*;
import cn.itsource.ymcc.mapper.*;
import cn.itsource.ymcc.openfeign.EsCourseOpenFeign;
import cn.itsource.ymcc.openfeign.MediaOpenFeign;
import cn.itsource.ymcc.producer.ICourseMessageProducer;
import cn.itsource.ymcc.result.JsonResult;
import cn.itsource.ymcc.service.ICourseService;
import cn.itsource.ymcc.util.AssertUtil;
import cn.itsource.ymcc.util.LoginContext;
import cn.itsource.ymcc.util.UserContext;
import cn.itsource.ymcc.vo.CourseVo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zongchangjiang
 * @since 2023-07-26
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {
    @Autowired
    private CourseDetailMapper courseDetailMapper;
    @Autowired
    private CourseMarketMapper courseMarketMapper;
    @Autowired
    private CourseChapterMapper courseChapterMapper;
    @Autowired
    private CourseResourceMapper courseResourceMapper;
    @Autowired
    private TeacherMapper teacherMapper;
    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private CourseTypeMapper courseTypeMapper;

    @Autowired
    private EsCourseOpenFeign esCourseOpenFeign;
    @Autowired
    private CourseSummaryMapper courseSummaryMapper;
    @Autowired
    private ICourseMessageProducer iCourseMessageProducer;

    @Autowired
    private MediaOpenFeign mediaOpenFeign;


    @Transactional
    @Override
    public JsonResult add(CourseVo courseVo) {
        JSONObject login = (JSONObject)LoginContext.getLogin();
        //得到当前用户信息
        String username = login.get(UserContext.USERNAME).toString();
        String id = login.get("id").toString();

        Course course = courseVo.getCourse();
        //处理老师
        List<Teacher> teachers = teacherMapper.selectBatchIds(courseVo.getTeacharIds());
        String teacherNames = teachers.stream()
                .map(Teacher::getName)  // 使用map  就只取某一个值
                .collect(Collectors.joining(","));//收集  使用，做分割
        course.setTeacherNames(teacherNames);
        //数据补充
        course.setStatus(RConst.Num.INT_0);
        //当前操作的人
        course.setLoginUserName(username);
        course.setLoginId(Long.valueOf(id));
        baseMapper.insert(course);//只要新增后 就能取到id
        //保存老师和课程的关系
        courseMapper.saveCourseAndTeacher(course.getId(),courseVo.getTeacharIds());
        //详情
        CourseDetail courseDetail = courseVo.getCourseDetail();
        courseDetail.setId(course.getId());
        courseDetailMapper.insert(courseDetail);
        //销售信息
        CourseMarket courseMarket = courseVo.getCourseMarket();
        courseMarket.setId(course.getId());
        courseMarketMapper.insert(courseMarket);
        //资源
        CourseResource courseResource = courseVo.getCourseResource();
        courseResource.setCourseId(course.getId());
        courseResourceMapper.insert(courseResource);

        //构建 courseSummary 的默认值
        CourseSummary courseSummary = new CourseSummary();
        courseSummary.setCommentCount(0);
        courseSummary.setSaleCount(0);
        courseSummary.setViewCount(0);
        courseSummary.setId(course.getId());
        courseSummaryMapper.insert(courseSummary);

        return JsonResult.success();
    }

    @Override
    public JsonResult findCourse(Long id) {
        Map<String,Object> result = new HashMap<>();
        //怎么把数据查询出来
        Course course = baseMapper.selectById(id);
        result.put("course",course);
        List<CourseResource> courseResources = courseResourceMapper
                .selectList(new LambdaQueryWrapper<CourseResource>()
                .eq(CourseResource::getCourseId, id));
        result.put("courseResources",courseResources);
        CourseMarket courseMarket = courseMarketMapper.selectById(id);
        result.put("courseMarket",courseMarket);
        CourseDetail courseDetail = courseDetailMapper.selectById(id);
        result.put("courseDetail",courseDetail);
        List<Long> longs = courseMapper.selectTeacherByCourseId(id);
        result.put("teacharIds",longs);

        Long courseTypeId = course.getCourseTypeId();
        CourseType courseType = courseTypeMapper.selectById(courseTypeId);
        result.put("courseType",courseType);
        return JsonResult.success().setData(result);
    }

    @Override
    public JsonResult edit(CourseVo courseVo) {
        //得到当前用户信息
        JSONObject login = (JSONObject)LoginContext.getLogin();
        //得到当前用户信息
        String username = login.get(UserContext.USERNAME).toString();
        String id = login.get("id").toString();

        Course course = courseVo.getCourse();
        course.setLoginUserName(username);
        course.setLoginId(Long.valueOf(id));

        List<Teacher> teachers = teacherMapper.selectBatchIds(courseVo.getTeacharIds());
        String teacherNames = teachers.stream()
                .map(Teacher::getName)  // 使用map  就只取某一个值
                .collect(Collectors.joining(","));//收集  使用，做分割
        course.setTeacherNames(teacherNames);
        baseMapper.updateById(course);
        //老师问题
        courseMapper.deleteTeacherByCourseId(course.getId());
        //保存老师和课程的关系
        courseMapper.saveCourseAndTeacher(course.getId(),courseVo.getTeacharIds());

        CourseDetail courseDetail = courseVo.getCourseDetail();
        courseDetail.setId(course.getId());
        courseDetailMapper.updateById(courseDetail);

        CourseMarket courseMarket = courseVo.getCourseMarket();
        courseMarket.setId(course.getId());
        courseMarketMapper.updateById(courseMarket);

        CourseResource courseResource = courseVo.getCourseResource();
        courseResource.setCourseId(course.getId());
        courseResourceMapper.update(courseResource, new LambdaQueryWrapper<CourseResource>()
                .eq(CourseResource::getCourseId, course.getId()));
        return JsonResult.success();
    }

    @Override
    public JsonResult onLineCourse(List<Long> ids) {
        AssertUtil.isFalse(ids.size() == RConst.Num.INT_0,"请选择未上线的数据");
        //要看当前选中的数据  有没有上线的   如果有上线的 就直接排除
        List<Course> courses = baseMapper.selectList(new QueryWrapper<Course>()
                .eq("status",RConst.Num.INT_0)
                .in("id",ids));//可以提高性能

        AssertUtil.isFalse(courses.size() == RConst.Num.INT_0,"请选择未上线的数据");

        List<CourseDoc> courseDocs = new ArrayList<>();
        //一下数据一定未上线的数据    修改状态
        List<Course> upCourse = courses.stream().map(course -> {
            course.setStatus(RConst.Num.INT_1);
            course.setOnlineTime(new Date());
            //构建CourseDoc
            builderCourseDoc(course,courseDocs);
            return course;
        }).collect(Collectors.toList());
        //修改
        super.updateBatchById(upCourse);
        //将上线数据也要保存到es中
        JsonResult jsonResult = esCourseOpenFeign.saveCourseDoc(courseDocs);
        //使用MQ发送消息
        courseDocs.forEach(courseDoc -> iCourseMessageProducer.sendMessage(courseDoc));

        return jsonResult;
    }

    /**
     * 怎么去写代码
     *    自己得明白要去实现什么功能
     * @param courseId
     * @return
     */
    @Override
    public JsonResult getDetail(Long courseId) {
        //数据从哪里来   不考虑性能  直接查询数据库
        //               考虑性能   查询es
        //使用open远程调用  如果返回是对象 那么open会自动转换为linkedHashMap
        //解决方案  被调用方法 返回JSON字符串
        JsonResult jsonResult = esCourseOpenFeign.queryOne(courseId);
        AssertUtil.isTrue(jsonResult.getSuccess(),"课程未上架");

        String courseDocString = jsonResult.getData().toString();
        CourseDoc courseDoc = JSONObject.parseObject(courseDocString, CourseDoc.class);
        //数据封装
        Map<String, Object> result = new HashMap<>();

        Course course = new Course();
        BeanUtils.copyProperties(courseDoc,course);
        result.put("course",course);

        course.setStartTime(new Date(courseDoc.getStartTime()));
        course.setEndTime(new Date(courseDoc.getEndTime()));
        course.setOnlineTime(new Date(courseDoc.getOnlineTime()));
        course.setStatus(1);

        CourseMarket courseMarket = new CourseMarket();
        BeanUtils.copyProperties(courseDoc,courseMarket);
        courseMarket.setPrice(new BigDecimal(courseDoc.getPrice()));
        courseMarket.setPriceOld(new BigDecimal(courseDoc.getPriceOld()));
        result.put("courseMarket",courseMarket);
        //自己去查询
        List<CourseChapter> courseChapter = courseChapterMapper.selectList(new QueryWrapper<CourseChapter>()
                .eq("course_id",courseId));
        //查询媒体数据
        JsonResult jsonResult1 = mediaOpenFeign.mediaFileByCourseId(courseId);
        if(jsonResult1.getSuccess()){
            String medias = jsonResult1.getData().toString();
            List<MediaFile> mediaFileList = JSONObject.parseArray(medias, MediaFile.class);
            //将对应的 媒体数据放入到对应的章节里面
            for (CourseChapter chapter : courseChapter) {
                for (MediaFile mediaFile : mediaFileList) {
                    if(chapter.getId().equals(mediaFile.getChapterId())){
                        chapter.getMediaFiles().add(mediaFile);
                    }
                }
            }
        }
        result.put("courseChapters",courseChapter);


        List<Teacher> teacher = teacherMapper.selectTeacherByCourseId(courseId);
        result.put("teachers",teacher);

        CourseDetail courseDetail = new CourseDetail();
        BeanUtils.copyProperties(courseDoc,courseDetail);
        result.put("courseDetail",courseDetail);

        CourseSummary courseSummary = new CourseSummary();
        BeanUtils.copyProperties(courseDoc,courseSummary);
        result.put("courseSummary",courseSummary);

        return JsonResult.success().setData(result);
    }

    @Override
    public JsonResult info(List<Long> ids) {
        if(ids.size() > 0){
            List<CourseDoc> courseDocs = new ArrayList<>();
            for (Long id : ids) {
                JsonResult jsonResult = esCourseOpenFeign.queryOne(id);
                String s = jsonResult.getData().toString();
                CourseDoc courseDoc = JSON.parseObject(s, CourseDoc.class);
                courseDocs.add(courseDoc);
            }
            return JsonResult.success().setData(courseDocs);
        }
        return JsonResult.error("请选择正确的数据");
    }

    private void builderCourseDoc(Course course, List<CourseDoc> courseDocs) {
        CourseDoc courseDoc = new CourseDoc();
        //主表
        BeanUtils.copyProperties(course,courseDoc);
        //手动设置
        courseDoc.setStartTime(course.getStartTime().getTime());//转为时间戳
        courseDoc.setEndTime(course.getEndTime().getTime());
        courseDoc.setOnlineTime(course.getOnlineTime().getTime());
        //课程类型名称
        CourseType courseType = courseTypeMapper.selectById(course.getCourseTypeId());
        courseDoc.setCourseTypeName(courseType.getName());
        //课程详情
        CourseDetail courseDetail = courseDetailMapper.selectById(course.getId());
        BeanUtils.copyProperties(courseDetail,courseDoc);
        //课程销售信息
        CourseMarket courseMarket = courseMarketMapper.selectById(course.getId());
        BeanUtils.copyProperties(courseMarket,courseDoc);
        courseDoc.setPrice(courseMarket.getPrice().doubleValue());
        courseDoc.setPriceOld(courseMarket.getPriceOld().doubleValue());
        //课程统计
        CourseSummary courseSummary = courseSummaryMapper.selectById(course.getId());
        BeanUtils.copyProperties(courseSummary,courseDoc);
        courseDocs.add(courseDoc);
    }
}
